<?php


namespace app\common\cachemodel;


use app\common\cachemodel\lucky\AppUserAdornInfo;
use app\common\lib\ConfigManage;
use app\common\lib\Util;
use app\common\model\ArticleCollect;
use app\common\model\ArticleGood;
use app\common\model\BaseCache;
use XznsTools\cache\CacheManage;

class Article extends BaseCache
{
    protected $table = 'wechatadmin.system_article';

    protected $cacheModel = 'content.article_info';

    /**
     * 获取最新的文章信息
     * @param $headers
     * @return array|bool|\PDOStatement|string|\think\Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getNewestArticle($headers)
    {
        $version = $headers['version'] ?? '';
        $appType = $headers['app-type'] === 'android' ? 1 : 2; // 手机类型 1安卓 2IOS
        $articleInfo = $this->alias('a')
            ->join('wechatadmin.system_article_version av', 'a.id=av.aid', 'left')
            ->join('wechatadmin.system_app_version v', 'av.version_id=v.id', 'left')
            ->where(function ($query) use ($appType, $version)
            {
                $query->where(['a.status' => 1, 'a.publish_time' => ['<', date('Y-m-d H:i:s')], 'v.type' => $appType, 'v.version_name' => 'V' . $version, 'a.is_ignore_version' => 0, 'a.cid' => [['<', 4], ['>', 42], 'or']]);
            })->whereOr(function ($query)
            {
                $query->where(['a.status' => 1, 'a.publish_time' => ['<', date('Y-m-d H:i:s')], 'a.is_ignore_version' => 1, 'a.cid' => [['<', 4], ['>', 42], 'or']]);
            })
            ->order('a.id DESC')
            ->field('a.id,a.title')
            ->find();//获取最新的文章信息
        return $articleInfo;
    }

    /**
     * 获取评论信息 列表信息
     * @param int|null $uid
     * @param int $cid 栏目ID
     * @param int $resType 返回数据格式 1=> 旧版本数据格式 2=>新版本（2.0.0）数据格式
     * @param int $page
     * @param int $limit
     * @return array
     * @throws \Exception
     */
    public function getPageArticleList($uid, int $cid, int $resType = 1, int $page = 1, int $limit = 10): array
    {
        $thisPageData = $this->getArticlePageIds($cid, $page, $limit);

        if ($thisPageData['data'])
        {
            // 通过ids 批量获取话题详情
            $articleDatas = $this->batchGetInfo($thisPageData['data'], ['read', 'read_base', 'good', 'title', 'introduction', 'author', 'avatar', 'thumb', 'publish_time', 'collect', 'is_hot', 'a_id', 'author_type']);
            // // 重组详情数据
            $thisPageData['data'] = $this->articleListDataReset($uid, $thisPageData['data'], $articleDatas, $resType);
        }

        return $thisPageData;
    }

    /**
     * 批量获取文章详情
     * @param array $ids
     * @param array $filed
     * @return array
     * @throws \Exception
     */
    public function batchGetInfo(array $ids, array $filed = []): array
    {
        $articleDatas = CacheManage::getInstance()->setCacheConfig($this->cacheModel)
            ->batchGetCache($ids, function ($ids)
            {
                try
                {
                    $datas = $this->alias('a')
                        ->join('wechatadmin.zhunle_article_author u', 'a.aid=u.id', 'LEFT')
                        ->where(['a.id' => ['in', $ids]])
                        // 2022-05-24 新增作者类型字段【u.type author_type】 1=>官方,2=>女神，用来处理特殊装扮
                        ->column('a.id,a.title,a.introduction,a.content,u.uid a_id,u.name author,u.thumb avatar,u.type author_type,a.thumb,a.publish_time,a.good,a.collect,a.read,a.read_base,a.is_hot,a.comment', 'a.id');
                    foreach ($datas as $k => $data)
                    {
                        $datas[$k]['publish_time'] = strtotime($data['publish_time']);
                        $cids = (new ArticleCategoryMiddle())->where('aid', $data['id'])->column('aid', 'cid');
                        $datas[$k]['cids'] = implode(',', array_keys($cids));
                    }
                }
                catch (\Exception $e)
                {
                    $datas = [];
                }
                return $datas;
            }, $filed, 'list_details');
        return $articleDatas;
    }

    /**
     * 旧版本 文章详情重组
     * @param int|null $uid
     * @param int $id
     * @param array $articleDetail
     * @param int $time_type 0=>时间戳,1=>字符串
     * @return array
     * @throws \Exception
     */
    public function articleDetailDataReset($uid, int $id, array $articleDetail, int $time_type = 1): array
    {
        if ($uid)
        {   // 登录状态
            $goods = (new ArticleGood())->getGoodFromCache($uid, 1);
            $collect = array_keys((new ArticleCollect())->getUserAllCollectFromCache($uid, 1));
            $reads = (new ArticleRead())->getUserArticleReadIds($uid, 1);
        } else
        {
            $goods = [];
            $collect = [];
            $reads = [];
        }
        $readNum = ($articleDetail['read'] ?? 0) + ($articleDetail['read_base'] ?? 0);
        // 点赞数量计算
        $goodNum = ($articleDetail['good'] ?? 0) + floor($readNum / 30);
        $resData = [
            'id' => $id,
            'title' => $articleDetail['title'] ?? '',
            'introduction' => $articleDetail['introduction'] ?? '',
            'content' => $articleDetail['content'] ?? '',
            'author' => $articleDetail['author'] ?? '',
            'avatar' => $articleDetail['avatar'] ?? '',
            'thumb' => $articleDetail['thumb'] ?? '',
            'publish_time' => $time_type ? date('Y-m-d H:i:s') : $articleDetail['publish_time'],
            'good' => (int)$goodNum,
            'collect' => (int)($articleDetail['collect'] ?? ''),
            'read' => $readNum,
            'is_hot' => (int)($articleDetail['is_hot'] ?? 0),
            'is_read' => in_array($id, $reads),
            'good_status' => in_array($id, $goods),
            'collect_status' => in_array($id, $collect),
            'a_id' => (int)($articleDetail['a_id'] ?? 0)
        ];

        return $resData;
    }

    /**
     * 获取栏目下，分页数据ID
     * @param int $cid
     * @param int $page
     * @param int $limit
     * @return array|mixed
     * @throws \Exception
     */
    public function getArticlePageIds(int $cid, int $page, int $limit)
    {
        $ids = CacheManage::getInstance()->setCacheConfig($this->cacheModel, $cid)
            ->setSort('desc')->ZsGetIocData('list', function () use ($cid)
            {
                $data = $this->alias('a')
                    ->join('wechatadmin.system_article_category ac', 'a.id=ac.aid')
                    ->where('a.status=1 and ac.cid=' . $cid)
                    ->whereTime('a.publish_time', '<', date('Y-m-d H:i:s'))
                    ->column('a.sort,a.publish_time', 'a.id');
                $ids = [];

                foreach ($data as $id => $val)
                {
                    $ids[$id] = (float)($val['sort'] . '.' . strtotime($val['publish_time']));
                }
                arsort($ids);
                return $ids;
            });

        $themeIds = [];
        $total = count($ids); // 总话题数
        $lastPage = $page < 1 ? 1 : (int)ceil($total / $limit); // 总页数

        if ($page < 1)
        { // 获取所有ID
            $themeIds = $ids;
        } elseif ($page > 0 && $page <= $lastPage)
        { // 第分页IDS
            $star = ($page - 1) * $limit;
            $themeIds = array_slice($ids, $star, $limit);
        }

        return [
            'total' => $total,// 记录总数
            'per_page' => $page < 1 ? -1 : $limit,// 每页多少条
            'current_page' => $page,// 当前页数
            'last_page' => $lastPage,// 总页数
            'data' => $themeIds,
        ];
    }

    /**
     * 获取分页数据ID
     * @param $uid
     * @param $resType
     * @param int $page
     * @param int $limit
     * @return array|mixed
     * @throws \Exception
     */
    public function getArticleIndexIds($uid, $resType, int $page = 1, int $limit = 10)
    {
        $version = request()->header('version', '1.0.0');
        $appType = request()->header('app-type', '');
        $cacheId = $appType . '_' . $version;

        $ids = CacheManage::getInstance()->setCacheConfig('content.article_index_info', $cacheId)
            ->setSort('desc')->ZsGetIocData('list', function () use ($limit, $appType, $version)
            {
                $data = $this->alias('a')
                    ->join('wechatadmin.system_article_version av', 'a.id=av.aid', 'left')
                    ->join('wechatadmin.system_app_version v', 'av.version_id=v.id', 'left')
                    ->where(function ($query) use ($appType, $version)
                    {
                        $query->where(['a.status' => 1, 'a.is_recommend' => 1, 'a.publish_time' => ['<', date('Y-m-d H:i:s')], 'v.type' => $appType, 'v.version_name' => 'V' . $version]);
                    })->whereOr(function ($query)
                    {
                        $query->where(['a.status' => 1, 'a.is_recommend' => 1, 'a.publish_time' => ['<', date('Y-m-d H:i:s')], 'a.is_ignore_version' => 1]);
                    })
                    ->order('a.sort DESC,a.publish_time DESC')
                    ->column('a.sort,a.publish_time', 'a.id');

                $ids = [];
                foreach ($data as $id => $val)
                {
                    $ids[$id] = (float)($val['sort'] . '.' . $val['publish_time']);
                }
                arsort($ids);
                return $ids;
            });
        $data = [];

        $aIds = [];
        $total = count($ids); // 总文章数
        $lastPage = $page < 1 ? 1 : (int)ceil($total / $limit); // 总页数

        if ($page < 1)
        { // 获取所有ID
            $aIds = $ids;
        } elseif ($page > 0 && $page <= $lastPage)
        { // 第分页IDS
            $star = ($page - 1) * $limit;
            $aIds = array_slice($ids, $star, $limit);
        }

        if ($aIds)
        {
            // 通过ids 批量获取话题详情
            $articleDatas = $this->batchGetInfo($aIds, ['read', 'read_base', 'good', 'title', 'introduction', 'author', 'avatar', 'thumb', 'publish_time', 'collect', 'is_hot', 'a_id', 'author_type']);
            // // 重组详情数据
            $data = $this->articleListDataReset($uid, $aIds, $articleDatas, $resType);
        }

        return [
            'total' => $total,// 记录总数
            'per_page' => $page < 1 ? -1 : $limit,// 每页多少条
            'current_page' => $page,// 当前页数
            'last_page' => $lastPage,// 总页数
            'data' => $data,
        ];
    }

    /**
     * 文章数据重组 新版本文章信息
     * @param int|null $uid
     * @param array $ids
     * @param array $articleDatas
     * @param int $resType 返回数据格式 1=> 旧版本数据格式 2=>新版本（2.0.0）数据格式
     * @return array
     * @throws \Exception
     */
    protected function articleListDataReset($uid, array $ids, array $articleDatas, int $resType): array
    {
        if ($uid)
        {   // 登录状态
            $goods = (new ArticleGood())->getGoodFromCache($uid, 1);
            $reads = (new ArticleRead())->getUserArticleReadIds($uid, 1);
        } else
        {
            $goods = [];
            $reads = [];
        }

        $resData = [];
        $configModel = new ConfigManage();
        foreach ($ids as $id)
        {
            $readNum = ($articleDatas[$id]['read'] ?? 0) + ($articleDatas[$id]['read_base'] ?? 0);
            // 点赞数量计算
            $goodNum = ($articleDatas[$id]['good'] ?? 0) + floor($readNum / 30);

            if ($resType === 1)
            {   // 旧版本格式
                $resData[] = [
                    'id' => (int)$id,
                    'title' => $articleDatas[$id]['title'] ?? '',
                    'introduction' => $articleDatas[$id]['introduction'] ?? '',
                    'author' => $articleDatas[$id]['author'] ?? '',
                    'avatar' => $articleDatas[$id]['avatar'] ?? '',
                    'thumb' => $articleDatas[$id]['thumb'] ?? '',
                    'publish_time' => $articleDatas[$id]['publish_time'] ?? 0,
                    'good' => $goodNum,
                    'collect' => (int)($articleDatas[$id]['collect'] ?? ''),
                    'read' => $readNum,
                    'is_hot' => (int)($articleDatas[$id]['is_hot'] ?? 0),
                    'is_read' => in_array($id, $reads),
                    'good_status' => in_array($id, $goods),
                ];
            } else
            {
                // 获取作者当前装扮信息
                $authorType = (int)($articleDatas[$id]['author_type'] ?? 0);
                $adorn = (new AppUserAdornInfo())->getUserAdornInfo(0, $authorType ?: 3);
                $userType = $configModel->innerUser((int)($articleDatas[$id]['a_id'] ?? 0));
                // 新版本数据格式 2.0.0 版本开始
                $resData[] = [
                    'id' => (int)$id,
                    'title' => $articleDatas[$id]['title'] ?? '',
                    'introduction' => $articleDatas[$id]['introduction'] ?? '',
                    'author' => $articleDatas[$id]['author'] ?? '',
                    'avatar' => $articleDatas[$id]['avatar'] ?? '',
                    'thumb' => $articleDatas[$id]['thumb'] ?? '',
                    'publish_time' => Util::timeToStr($articleDatas[$id]['publish_time']),
                    'good_num' => abs($goodNum),
                    'read_num' => $readNum,
                    'is_hot' => (int)($articleDatas[$id]['is_hot'] ?? 0),
                    'is_read' => in_array($id, $reads) ? 1 : 0,
                    'is_good' => in_array($id, $goods) ? 1 : 0,
                    'type' => 1,//类型 1=》图文（可分享），2=》竖屏视频，3=》横屏视屏，4》音频，5=》公告
                    'user_type' => $userType,
                    'avatar_adorn' => $adorn['adorn_info']['reality_img'],
                    'tag' => $adorn['tag_info']['reality_img'],
                ];
            }
        }

        return $resData;
    }
}
